import Foundation

typealias BtnActionBlock = ((UIButton)->Void)

open class AppCustomButton: UIButton { }

public extension AppCustomButton {

    private struct AssociatedKeys {
        static var eventInterval = "eventInterval"
        static var eventUnavailable = "eventUnavailable"
    }
    
    /// 重复点击的时间 属性设置
    var eventInterval: TimeInterval {
        get {
            if let interval = objc_getAssociatedObject(self, &AssociatedKeys.eventInterval) as? TimeInterval {
                return interval
            }
            return 1
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.eventInterval, newValue as TimeInterval, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 按钮不可点 属性设置
    private var eventUnavailable : Bool {
        get {
            if let unavailable = objc_getAssociatedObject(self, &AssociatedKeys.eventUnavailable) as? Bool {
                return unavailable
            }
            return false
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.eventUnavailable, newValue as Bool, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 新建初始化方法,在这个方法中实现在运行时方法替换
    class func initializeMethod() {
        
        MYLog(type(of: self))
        
        let selector = #selector(AppCustomButton.sendAction(_:to:for:))
        let newSelector = #selector(addNewAction(_:to:for:))
        
        let method = class_getInstanceMethod(AppCustomButton.self, selector)!
        let newMethod = class_getInstanceMethod(AppCustomButton.self, newSelector)!
        
        if class_addMethod(AppCustomButton.self, selector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)) {
            class_replaceMethod(AppCustomButton.self, newSelector, method_getImplementation(method), method_getTypeEncoding(method))
        } else {
            method_exchangeImplementations(method, newMethod)
        }
    }
    
    /// 在这个方法中
    @objc private func addNewAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        if eventUnavailable == false {
            eventUnavailable = true
            addNewAction(action, to: target, for: event)
            // 延时
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + eventInterval, execute: {
                self.eventUnavailable = false
            })
        }
    }
    
    /// 交换回原来的方法
    class func initializeOldMethod() {
        let selector = #selector(UIButton.sendAction(_:to:for:))
        let newSelector = #selector(addOldAction(_:to:for:))
        
        let method = class_getInstanceMethod(UIButton.self, selector)!
        let newMethod = class_getInstanceMethod(UIButton.self, newSelector)!
        
        if class_addMethod(UIButton.self, selector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)) {
            class_replaceMethod(UIButton.self, newSelector, method_getImplementation(method), method_getTypeEncoding(method))
        } else {
            method_exchangeImplementations(method, newMethod)
        }
    }
    @objc private func addOldAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        addNewAction(action, to: target, for: event)
    }
}

/// 定义button相对label的位置
public enum RGButtonImagePosition {
    case top          //图片在上，文字在下，垂直居中对齐
    case bottom       //图片在下，文字在上，垂直居中对齐
    case left         //图片在左，文字在右，水平居中对齐
    case right        //图片在右，文字在左，水平居中对齐
}

public extension UIButton {
    
    /// - Description 设置Button图片的位置
    /// - Parameters:
    ///   - style: 图片位置
    ///   - spacing: 按钮图片与文字之间的间隔
    func imagePosition(style: RGButtonImagePosition, spacing: CGFloat) {
        guard let imageWidth = self.currentImage?.size.width,
              let imageHeight = self.currentImage?.size.height else { return }
        
        var labelWidth: CGFloat! = 0.0
        var labelHeight: CGFloat! = 0.0
        
        if #available(iOS 8.0, *) {
            labelWidth = self.titleLabel?.intrinsicContentSize.width
            labelHeight = self.titleLabel?.intrinsicContentSize.height
        }else{
            labelWidth = self.titleLabel?.frame.size.width
            labelHeight = self.titleLabel?.frame.size.height
        }
        
        //初始化imageEdgeInsets和labelEdgeInsets
        var imageEdgeInsets = UIEdgeInsets.zero
        var labelEdgeInsets = UIEdgeInsets.zero
        
        //根据style和space得到imageEdgeInsets和labelEdgeInsets的值
        switch style {
        case .top:
            //上 左 下 右
            imageEdgeInsets = UIEdgeInsets.init(top: -labelHeight-spacing, left: 0, bottom: 0, right: -labelWidth)
            labelEdgeInsets = UIEdgeInsets.init(top: 0, left: -imageWidth, bottom: -spacing-imageHeight, right: 0)
            break;
            
        case .left:
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -spacing, bottom: 0, right: spacing)
            labelEdgeInsets = UIEdgeInsets.init(top: 0, left: spacing, bottom: 0, right: -spacing)
            break;
            
        case .bottom:
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: 0, bottom: -labelHeight!-spacing, right: -labelWidth)
            labelEdgeInsets = UIEdgeInsets.init(top: -imageHeight-spacing, left: -imageWidth, bottom: 0, right: 0)
            break;
            
        case .right:
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: labelWidth+spacing, bottom: 0, right: -labelWidth-spacing)
            labelEdgeInsets = UIEdgeInsets.init(top: 0, left: -imageWidth-spacing, bottom: 0, right: imageWidth+spacing)
            break;
            
        }
        
        self.titleEdgeInsets = labelEdgeInsets
        self.imageEdgeInsets = imageEdgeInsets
        
    }
    
}


